#include "lianxi01.h"
//申请空间
UsrList *mkUsrList()
{
    UsrList *list=(UsrList*)malloc(sizeof(UsrList));
    if(NULL==list)
    {
        printf("malloc list failed!\n");
        exit(EXIT_FAILURE);
    }
    memset(list,0,sizeof(UsrList));
    return list;
}
//申请空间
UsrNode *mkUsrNode()
{
    UsrNode *node=(UsrNode*)malloc(sizeof(UsrNode));
    if(NULL==node)
    {
        printf("malloc node failed!\n");
        exit(EXIT_FAILURE);
    }
    memset(node,0,sizeof(UsrNode));
    return node;
}
//插入
void insert(UsrList *list, UsrNode *node)
{
	if (NULL == list || NULL == node)
	{
		return;
	}
	node->pNext = list->pFirstNode;
	list->pFirstNode = node;
	list->iLen++;
}
//匹配
UsrNode *findUsrByName(const UsrList *list, const char *name)
{
	UsrNode *node = NULL;
	if (NULL != list && NULL != name)
	{
		node = list->pFirstNode;
		while (NULL != node)
		{
			if (0 == strcmp(name, node->caUsrName))
			{
				break;
			}
			node = node->pNext;	
		}
	}
	return node;	
}
//打印
void display(const UsrList *list)
{
	if (NULL != list)
	{
		UsrNode *node = list->pFirstNode;
		while (NULL != node)
		{
			printf("usrname:%s;usrpwd:%s;age:%d\n"
				   , node->caUsrName, node->caUsrPwd
				   , node->iAge);
			node = node->pNext;
		}
	}
}

//打开文件
FILE *openFile(const char *path,const char *mode)
{
    FILE *file=NULL;
    if(NULL!=path && NULL != mode)
    {
        file=fopen(path,mode);
        if(NULL ==file)
        {
            printf("open %s failed -> %s\n",path,strerror(errno));
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        printf("参数不对...\n");
        exit(EXIT_FAILURE);
    }
    return file;
    
}

//将用户列表保存到文件中
void saveUsrListToFile(const char *path,const UsrList *list)
{
    if(NULL == path || NULL == list)
    {
        return;
    }
    FILE *file=openFile(path,"wb");
    UsrNode *node=list->pFirstNode;
    while(NULL != node)
    {
        printf("name:%s,pwd:%s\n",node->caUsrName,node->caUsrPwd);
        fwrite(node,sizeof(UsrNode),1,file);
        node=node->pNext;
    }
    fclose(file);
}

//将用户信息从文件中读取出来放到列表中
void loadUsrInfoFromFile(const char *path,UsrList *list)
{
    if(NULL == path || NULL == list)
    {
        return;
    }
    FILE *file=openFile(path,"rb");
    UsrNode *node=NULL;
    int ret=0;
    while(1)
    {
        node = mkUsrNode();
        ret=fread(node,sizeof(UsrNode),1,file);
        if(ret == 0)
        {
            free(node);
            node=NULL;
            if(feof(file))
            {
                break;
            }
            else if (ferror(file))
            {
                fclose(file);
                printf("read file error..\n");
                exit(EXIT_FAILURE);
            }
        }
        node->pNext=NULL;
        insert(list,node);
    }
    fclose(file);
}
//登录界面
int loginOrRegistFace()
{
    printf("^ ^\n");
    printf("1.登录\n");
    printf("2.注册\n");
    printf("0.退出\n");
    printf("请输入操作选项：\n");
    int iNum=0;
    //当没有正确输入时，循环将标准缓存区中的数据读取
    if(1!=scanf("%d",&iNum))
    {
        while('\n'!=getchar()){}
    }
    else
    {
        getchar();
    }
    return iNum;
    
}
//标准输入
static void getSTRFromSTDIN(char *arr,int count)
{
    if(NULL==arr||count<=0)
    {
        return;
    }
    //stdin标准输入
    fgets(arr,count,stdin);
    //查找字符串中是否包含'\n'
    //找到字符串中最后一个\n
    char *p = strchr(arr,'\n');
    if(NULL != p)//如果包含了，则将'\n'替换成'\0'
    {
        *p='\0';
    }
    else//若没有找到'\n',则表示缓冲区中还有数据
    {
        //循环读取
        while('\n' !=getchar()){}
    }
}
//注册
void regist(UsrList *list)
{
    char caUsrName[NAME_LEN]={'\0'};
    printf("请输入注册的用户名：\n");
    getSTRFromSTDIN(caUsrName,NAME_LEN);
    if(NULL!=findUsrByName(list,caUsrName))
    {
        printf("注册失败-->该用户名已存在\n");
    }
    else
    {
        char caUsrPwd[PWD_LEN]={'\0'};
        printf("请输入注册所用密码：\n");
        getSTRFromSTDIN(caUsrPwd,PWD_LEN);
        //产生节点保存用户名及密码
        UsrNode *node=mkUsrNode();
        strcpy(node->caUsrName,caUsrName);
        strcpy(node->caUsrPwd,caUsrPwd);
        insert(list,node);
        saveUsrListToFile(PATH_NAME,list);
    }
    
}

//登录
UsrNode * login(UsrList *list)
{
    UsrNode *node=NULL;
    if(NULL != list)
    {
        char caUsrName[NAME_LEN]={'\0'};
        printf("请输入用户名：\n");
        getSTRFromSTDIN(caUsrName,NAME_LEN);
        node=findUsrByName(list,caUsrName);
        if(NULL==node)
        {
            printf("登录失败-->该用户名不存在...\n");
        }
        else
        {
            char caUsrPwd[PWD_LEN]={'\0'};
            printf("请输入密码:\n");
            getSTRFromSTDIN(caUsrPwd,PWD_LEN);
            if(0 == strcmp(caUsrPwd,node->caUsrPwd))
            {
                printf("登陆成功...\n");
            }
            else
            {
                printf("登录失败-->用户名密码错误...\n");
                node=NULL;
            }
        }
    }
    else
    {
        printf("参数有误...\n");
    }
    return node;
}

//登录或注册存档
UsrNode* loginOrRegistOpe(UsrList*list)
{
    if(NULL == list)
    {
        return NULL;
    }
    UsrNode *node=NULL;
    int iNum=0;
    while (1)
	{
		iNum = loginOrRegistFace();
		switch (iNum)
		{
		case 1://登录
			node = login(list);
			break;
		case 2://注册
			regist(list);
			break;
		case 0://退出
			exit(EXIT_SUCCESS);
		default:
			printf("输入有误，请重新输入...\n");
			break;
		}
		if (NULL != node)
		{
			break;
		}
	}
	return node;
}

//用户界面
int usrOpeFace()
{
	printf("   ^_^\n");
	printf("1，显示全部用户信息\n");
	printf("2，显示本身信息\n");
	printf("3，修改密码\n");
	printf("0，退出登录\n");
	printf("请输入操作选项:\n");
	int iNum = 0;
	scanf("%d", &iNum);
	while ('\n' != getchar()){}

	return iNum;
}
//存档
void usrOpe(UsrList *list, UsrNode *node)
{
	if (NULL == list || NULL == node)
	{
		return;
	}

	int iNum = 0;
	while (1)
	{
		iNum = usrOpeFace();
		switch (iNum)
		{
		case 1: //显示全部信息
			display(list);
			break;
		case 2:
			printf("name:%s,pwd:%s,age:%d\n"
				   , node->caUsrName, node->caUsrPwd, node->iAge);
			break;
		case 3:
			printf("请输入新密码:\n");
			getSTRFromSTDIN(node->caUsrPwd, PWD_LEN);
			saveUsrListToFile(PATH_NAME, list);
			break;
		case 0:
			return;
		default:
			printf("输入有误...\n");
			break;
		}
	}
}